package com.wdb.modules.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wdb.modules.system.domain.Dept;
import com.wdb.modules.system.domain.dto.DeptExcelDTO;
import com.wdb.modules.system.domain.vo.DeptQueryCriteria;
import com.wdb.modules.system.mapper.DeptMapper;
import com.wdb.modules.system.service.DeptService;
import com.wdb.utils.PageResult;
import com.wdb.utils.PageUtil;
import com.wdb.utils.SecurityUtils;
import com.wdb.utils.StringUtils;
import com.wdb.utils.enums.DataScopeEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author: wendaobai@qq.com
 * @date: 2024/1/19 0019 9:56
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {
  private final DeptMapper deptMapper;

  @Override
  public Set<Dept> findByRoleId(Long id) {
    return deptMapper.findByRoleId(id);
  }

  @Override
  public List<Dept> findByPid(Long id) {
    return deptMapper.findByPid(id);
  }

  @Override
  public PageResult<Dept> findAll(DeptQueryCriteria criteria, boolean isQuery)
      throws IllegalAccessException {
    QueryWrapper<Dept> queryWrapper = new QueryWrapper<>();
    String dataScopeType = SecurityUtils.getDataScopeType();
    if (isQuery) {
      if (dataScopeType.equals(DataScopeEnum.ALL.getValue())) {
        criteria.setPidIsNull(true);
      }
      // 没有任何查询条件时是全量查询
      List<Field> fields = StringUtils.getAllFields(criteria.getClass(), new ArrayList<>());
      // 过滤的属性
      List<String> fieldNames =
          new ArrayList<String>() {
            {
              add("pidIsNull");
              add("enabled");
            }
          };
      for (Field field : fields) {
        field.setAccessible(true);
        Object val = field.get(criteria);
        if (fieldNames.contains(field.getName())) {
          continue;
        }
        if (ObjectUtil.isNotNull(val)) {
          // 如果有查询条件就不是条件查询
          criteria.setPidIsNull(null);
          break;
        }
      }
    }
    queryWrapper.lambda().isNull(criteria.getPidIsNull() != null, Dept::getPid);
    queryWrapper.lambda().eq(criteria.getPid() != null, Dept::getPid, criteria.getPid());
    queryWrapper
        .lambda()
        .eq(criteria.getEnabled() != null, Dept::getEnabled, criteria.getEnabled());

    if ((criteria.getCreateTime() != null && criteria.getCreateTime().size() > 1)) {
      queryWrapper
          .lambda()
          .between(
              Dept::getCreateTime,
              criteria.getCreateTime().get(0),
              criteria.getCreateTime().get(1));
    }

    queryWrapper
        .lambda()
        .like(
            criteria.getName() != null && criteria.getName().trim() != "",
            Dept::getName,
            criteria.getName());
    queryWrapper.lambda().orderBy(true, false, Dept::getDeptSort);
    List<Dept> deptList = deptMapper.selectList(queryWrapper);
    return PageUtil.toPage(deptList);
  }

  /**
   * 需要开启事务
   *
   * @param resources dept
   */
  @Transactional(rollbackFor = Exception.class)
  @Override
  public void create(Dept resources) throws Exception {
    // 插入数据
    this.save(resources);
    // 更新父节点数据
    updateSubCnt(resources.getPid());
    // 清理自定义角色权限的datascope缓存
  }

  /**
   * 删除
   *
   * @param depts
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public void delete(HashSet<Dept> depts) throws Exception {
    for (Dept dept : depts) {
      deptMapper.deleteById(dept);
      updateSubCntByPid(dept.getPid());
    }
  }

  @Override
  public HashSet<Dept> getDeleteDepts(List<Dept> deptList, HashSet<Dept> depts) {
    for (Dept dept : deptList) {
      depts.add(dept);
      List<Dept> list = this.findByPid(dept.getId());
      if (CollectionUtil.isNotEmpty(list)) {
        // 递归查找字节点
        getDeleteDepts(list, depts);
      }
    }
    return depts;
  }

  @Override
  public void download(List<Dept> deptList, HttpServletResponse response) throws IOException {
    log.info("1111111111111");
    ArrayList<Map<String, Object>> list = new ArrayList<>();
    for (Dept dept : deptList) {
      HashMap<String, Object> map = new LinkedHashMap<>();
      map.put("部门名称", dept.getName());
      map.put("部门状态", dept.getEnabled() ? "启用" : "停用");
      map.put("创建日期", dept.getCreateTime());
      list.add(map);
    }
    // FileUtil.downloadExcel(list, response);
    // FileUtil.downloadEasyExcel(list, Dept.class, response);
    // easyexcel 实现

    ArrayList<DeptExcelDTO> deptExcelDTOArrayList = new ArrayList<>();
    for (Dept dept : deptList) {
      DeptExcelDTO deptExcelDTO = new DeptExcelDTO();
      deptExcelDTO.setName(dept.getName());
      deptExcelDTO.setEnabled(dept.getEnabled() ? "启用" : "停用");
      DateTime dateTime = new DateTime(dept.getCreateTime());
      deptExcelDTO.setCreateTime(dateTime.toString());
      deptExcelDTOArrayList.add(deptExcelDTO);
    }

    String path =
        "C:\\Users\\Administrator\\Desktop\\temp\\download\\"
            + "部门信息_"
            + System.currentTimeMillis()
            + ".xlsx";
    log.info("path:{}", path);
    log.info("deptExcelDTOArrayList:{}", deptExcelDTOArrayList);
    EasyExcel.write(path, DeptExcelDTO.class).sheet("模板").doWrite(deptExcelDTOArrayList);
  }

  private void updateSubCntByPid(Long pid) throws Exception {

    if (pid == null) {
      return;
    }
    int count = deptMapper.countByPid(pid);
    Dept dept = deptMapper.selectById(pid);
    dept.setSubCount(count);
    int i = deptMapper.updateById(dept);
    if (i == 0) {
      throw new Exception("删除失败");
    }
  }

  private void updateSubCnt(Long deptId) throws Exception {
    if (deptId != null) {
      Dept dept = deptMapper.selectById(deptId);
      dept.setSubCount(dept.getSubCount() + 1);
      int i = deptMapper.updateById(dept);
      if (i == 0) {
        throw new Exception("更新失败11");
      }
    }
  }
}
